
#include "../ui/ui_maincharts.h"
#include "maincharts.h"
#include <QTimer>
#include "../user/udp_mavlink.h"
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>


/**
 * 构造函数
 */
MainCharts::MainCharts(float * adder,uint8_t len):ui(new Ui::MainCharts)
{
    ui->setupUi(this);
    count = 0;
    //获取控件属性
    data_buff = ui->data_buff->value();
    window_width = ui->window_width->value();
    data_source = adder;
    m_axisX = new QValueAxis();
    m_axisY = new QValueAxis();
    m_axisX->setTitleText("时间");
    m_axisY->setTitleText("数值");

    m_axisX->setMin(10);
    m_axisY->setMin(-1);

    m_axisX->setMax(10);
    m_axisY->setMax(3);

    m_lineSeries = new QLineSeries();                              // 创建曲线绘制对象
    m_lineSeries->setPointsVisible(true);                          // 设置数据点可见
    m_lineSeries->setName("数据曲线");                            // 图例名称

    m_chart = new QChart();                                        // 创建图表对象
    m_chart->addAxis(m_axisX, Qt::AlignBottom);        // 将X轴添加到图表上
    m_chart->addAxis(m_axisY, Qt::AlignLeft);          // 将Y轴添加到图表上
    m_chart->addSeries(m_lineSeries);                              // 将曲线对象添加到图表上
    m_chart->setAnimationOptions(QChart::SeriesAnimations);     // 动画：能使曲线绘制显示的更平滑，过渡效果更好看

    m_lineSeries->attachAxis(m_axisX);                             // 曲线对象关联上X轴，此步骤必须在m_chart->addSeries之后
    m_lineSeries->attachAxis(m_axisY);                             // 曲线对象关联上Y轴，此步骤必须在m_chart->addSeries之后

    ui->graphicsView->setChart(m_chart);                           // 将图表对象设置到graphicsView上进行显示
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);       // 设置渲染：抗锯齿，如果不设置那么曲线就显得不平滑

    data_time = new QTimer(this);
    connect(data_time, SIGNAL(timeout()), this,SLOT(Charts_refsh()));
    data_time->start(ui->cycle->value());
}

/**
 * 析构函数
 */
MainCharts::~MainCharts() {
    delete ui;
}


/**
 * 刷新数据到图表
 */
void MainCharts::Charts_refsh() {

    //获取横坐标 滑块位置
    float x_pos = float((float)ui->window_slider->value()/100.0f);
    //转换为在缓存窗中的位置
    x_pos = x_pos * data_buff;
    //获取窗口宽度
    int x_width = ui->window_width->value();
    //计算在缓存中首位位置
    int min_x = x_pos - x_width / 2;
    int max_x = x_pos + x_width / 2;
    //限制坐标的范围 防止溢出
    if(min_x < 0) {
        min_x = 0;
    }
    if(max_x > data_buff) {
        max_x = data_buff;
    }

    //设置滑块的宽度动效
    set_SliderWidth((max_x-min_x),data_buff);

    //设置X轴的显示范围
    set_Chasrt_AxisX_Range((count-(data_buff-min_x)<0)?0:count-(data_buff-min_x),
        (count-(data_buff-max_x)<window_width)?window_width:count-(data_buff-max_x));

    if (refresh_flag) {
        m_lineSeries->append(QPointF(count,(float) (*data_source) ));
        count+=ui->cycle->value();
    }
}


/**
 * 设置滑块宽度 按照总宽度的百分比设置
 * @param width 当前宽度
 * @param all_width 总宽度
 */
void MainCharts:: set_SliderWidth(int width,int all_width) {
    //获取滑块的宽度 并除以缓存大小 以百分比设置滑块的宽度
    float width_precnt = static_cast<float>(width) / static_cast<float>(all_width);
    //计算滑块的实际宽度=比例 *当前slider的像素宽度
    int slider_width = (int)(width_precnt * (ui->window_slider->geometry().width()));
    if (slider_width < 50) {
        slider_width = 50;
    }
    //设置滑块的实际宽度
    //设置滑块大小的宽度
    QString style = "QSlider::groove:horizontal { height: 8px; background: #e0e0e0; }"
                   "QSlider::handle:horizontal {"
                   "    width: " + QString::number(slider_width) + "px;"
                   "    height: 20px;"
                   "    background: #2196F3;"
                   "    margin: -6px 0;"  // 垂直居中
                   "}";
    this->ui->window_slider->setStyleSheet(style);
}

//设置X轴的显示范围
void MainCharts::set_Chasrt_AxisX_Range(int min_x,int max_x) {
    //设置X轴的显示范围
    m_axisX->setMin(min_x);
    m_axisX->setMax(max_x);
}
//设置Y轴的显示范围
void MainCharts::set_Chasrt_AxisY_Range(int min_y,int max_y) {
    //设置Y轴的显示范围
    m_axisY->setMin(min_y);
    m_axisY->setMax(max_y);
}

/**
 * @brief 窗口宽度改变时触发的槽函数
 * @param arg1 键入的数字
 */
void MainCharts::on_window_width_valueChanged(int arg1) {
    if(arg1 > data_buff) {
        ui->window_width->setValue(data_buff);
        //发送消息弹窗 不能大于缓存大小
         QMessageBox::warning(this, "警告", "窗口宽度不能大于缓存大小");
    }
}
/*
 * @brief 缓存大小改变时触发的槽函数
 */
void MainCharts::on_data_buff_valueChanged(int arg1)
{
    data_buff = arg1;
}


/**
 * @brief 窗口滑块改变时触发的槽函数
 * @note 保存数据图窗到文件*/
void MainCharts::on_data_save_clicked() {
    //保存数据图窗到文件,(手动选择保存路径)
    QString fileName = QFileDialog::getSaveFileName(this, "保存数据图窗", "", "CSV(*.csv)");
    if(fileName.isEmpty()) {
        return;
    }
    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::warning(this, "保存失败", "无法保存文件");
        return;
    }
    QTextStream out(&file);
    for(int i=0;i<m_lineSeries->count();i++) {
        out << m_lineSeries->at(i).x() << "," << m_lineSeries->at(i).y() << "\n";
    }
    file.close();
    QMessageBox::information(this, "保存成功", "数据图窗已保存到" + fileName);
}

/**
 * @brief 清空数据图窗
 */
void MainCharts::on_clean_form_clicked()
{
    m_lineSeries->clear();
    count = 0;
}

/**
 * @brief 暂停刷新
 */
void MainCharts::on_pause_clicked()
{
    refresh_flag   = false;
}

/*
 * @brief 开始刷新
 */
void MainCharts::on_start_clicked()
{
    refresh_flag   = true;
}

void MainCharts::on_cycle_valueChanged(int arg1) {
    //设置刷新间隔
    data_time->setInterval(arg1);
}